package lt.startup.duobes;

import java.util.ArrayList;
import java.util.List;

import lt.startup.duobes.MyLocation.LocationResult;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

import com.crazyimp.utilities.ApiCalls;
import com.crazyimp.utilities.Parsers;
import com.crazyimp.utilities.Pothole;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;



public class PotholeActivity extends MapActivity {
	
	private static final int BUFFER_SIZE = 5;
	
	private SensorManager sensorManager;
	private Sensor sensor;
	private PotholeListener listener;
	private PotholeOverlay itemizedoverlay;
	private PotholeOverlay serverPotholeOverlays;
	private MyLocation locationizer;
	private Location location = null;
	private Location lastPothole = null;
	private MapView mapView;
	private Sender sender;
	private boolean capture;
	private Button startButton;
	private Handler handler;

	private ArrayList<Pothole> potHoles;
	private boolean serverOverlayInit = false;

	private PowerManager.WakeLock wakeLock;
	private float[] buffer = new float[BUFFER_SIZE];
	private int index = 0;
	private Location spotLocation;

	
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        sender = new Sender();
        
        Constants.loadPreferences(this);
        listener = new PotholeListener();
        
        mapView = (MapView) findViewById(R.id.mapview);
        Constants.map = mapView;
        capture = false;
        
        handler = new Handler();
        
        Drawable drawable = this.getResources().getDrawable(R.drawable.pin);
        itemizedoverlay = new PotholeOverlay (drawable, this);

        Drawable potDrawable = this.getResources().getDrawable(R.drawable.locationa);
        serverPotholeOverlays = new PotholeOverlay (potDrawable, this);
        
        locationizer = new MyLocation();
        locationizer.setRefreshing(true);
                
        Button settingsButton = (Button) findViewById(R.id.settings_button);
        settingsButton.setOnClickListener(new OnClickListener() {			
			@Override
			public void onClick(View v) {
				Intent intent = new Intent(getApplicationContext(), SettingsActivity.class);
				startActivity(intent);
			}
		});
        
        startButton = (Button) findViewById(R.id.start_button);
        startButton.setOnClickListener(new OnClickListener() {			
			@Override
			public void onClick(View v) {				
				if (capture){
					Thread thread = new Thread(new Runnable() {						
						@Override
						public void run() {
							sender.sendPoints();	
							handler.post(new Runnable() {								
								@Override
								public void run() {
									startButton.setEnabled(true);
									startButton.setText("Start");
								}
							});							
						}
					});
					thread.start();
					startButton.setEnabled(false);
				} else {
					startButton.setText("Upload");
				}
				capture = !capture;
			}
		});
        
        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
		sensor = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);   
		locationizer.getLocationFast(this, new LocationResult() {			
			@Override
			public void gotLocation(Location loc) {
				Constants.location = loc;
				location = loc;
			}
		});
		locationizer.getLocation(this, new LocationResult() {			
			@Override
			public void gotLocation(Location loc) {
				Constants.location = loc;
				location = loc;
			}
		});
		new ReadPots().execute();

		//});	

		
		PowerManager manager = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
		wakeLock = manager.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "Duobe");
		
    }
	private class ReadPots extends AsyncTask<Void, Void, String> {
		
		
		@Override
		protected String doInBackground(Void... arg0) {
			List<NameValuePair> data = new ArrayList<NameValuePair>();
			data.add(new BasicNameValuePair("action", "getmaps"));
			data.add(new BasicNameValuePair("minx", String.valueOf(-200)));
			data.add(new BasicNameValuePair("maxx", String.valueOf(200)));
			data.add(new BasicNameValuePair("miny", String.valueOf(-100)));
			data.add(new BasicNameValuePair("maxy", String.valueOf(100)));
			data.add(new BasicNameValuePair("limit", String.valueOf(40)));
			return ApiCalls.postData("handler.php", data);
		}

		@Override
		protected void onPostExecute(String result) {
			if (!isCancelled()) {
				potHoles = Parsers.parsePotholes(result);
				Log.e(Constants.LOG, "Putting poins");
				addServerPin();
				super.onPostExecute(result);
			}
		}
	}	
    @Override
	protected void onResume() {
		super.onResume();
		sensorManager.registerListener(listener, sensor, SensorManager.SENSOR_DELAY_FASTEST);
		wakeLock.acquire();
	} 
    
    
 
	@Override
	protected void onDestroy() {		        if (serverPotholeOverlays.size() == 1){
    	mapView.getOverlays().add(serverPotholeOverlays);
    }
    mapView.postInvalidate();
		locationizer.stopLocating();
		super.onStop();
	}
	   
	private void addPin(Location location){
		GeoPoint point = new GeoPoint((int)(location.getLatitude()*1000000),(int)(location.getLongitude()*1000000));
		OverlayItem overlayitem = new OverlayItem(point, "Duobe", "As baisi :)");
		itemizedoverlay.addOverlay(overlayitem);
		if (itemizedoverlay.size() == 1){
			mapView.getOverlays().add(itemizedoverlay);
		}
		mapView.postInvalidate();
	}
	private void addServerPin(){
		
        for(int i = 0; i < potHoles.size(); i++){
        	Log.e(Constants.LOG, "Putting pin in "+potHoles.get(i).longi+"&"+potHoles.get(i).lat);
        	GeoPoint point = new GeoPoint((int)(potHoles.get(i).lat*1000000),(int)(potHoles.get(i).longi*1000000));
        	OverlayItem overlayitem = new OverlayItem(point, "Duobe", "As baisi :)");
        	serverPotholeOverlays.addOverlay(overlayitem);
        }
        if (serverPotholeOverlays.size() == 1 || !serverOverlayInit){
        	mapView.getOverlays().add(serverPotholeOverlays);
        	serverOverlayInit = true;
        }
        mapView.postInvalidate();
    }
	
    
	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}
	
	private class PotholeListener implements SensorEventListener{
		private float x;
		private float y;
		private float z;
		boolean init;
		
		public PotholeListener(){
			init = true;
		}
		
		@Override
		public void onAccuracyChanged(Sensor sensor, int accuracy) {}

		@Override
		public void onSensorChanged(SensorEvent event) {
			if (!init && capture){
				float distance = (float) Math.sqrt(Math.pow(event.values[0]-x, 2)+Math.pow(event.values[1]-y, 2)+Math.pow(event.values[2]-z, 2));
				buffer[index] = distance;
				index = (index+1)%BUFFER_SIZE;
				if (index == 0) {
					float sum = 0;
					for (float dist : buffer){
						sum += dist;
					}
					sum /= BUFFER_SIZE;
					
					if (sum > Constants.sence){
						spotLocation = location;
					} else if (sum < Constants.sence && spotLocation != null){			
						if (location != null && location.distanceTo(spotLocation) < 0.1f){
							if (distance > Constants.sence && spotLocation != null ){
								if (lastPothole == null || spotLocation.distanceTo(lastPothole) > Constants.MIN_DISTANCE){
									addPin(spotLocation);
									double value = Math.sqrt(Math.pow((event.values[0]-x)/10.0, 2)+Math.pow((event.values[1]-y)/10.0, 2)+Math.pow((event.values[2]-z)/10.0, 2));
									sender.addPoint(spotLocation, value);
									lastPothole = new Location(spotLocation);
									startButton.setText("Upload("+sender.amount()+")");
								}
							}
						}
						spotLocation = null;
					}
					
				}
				
				
				
			}
			x = event.values[0];
			y = event.values[1];
			z = event.values[2];
			init = false;
		}	
	}

	@Override
	protected void onPause() {
		super.onPause();
		sensorManager.unregisterListener( listener);
		wakeLock.release();
	}
	
	
	
	
	
	
	
	
}